package server.handler;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import message.RpcRequestMessage;
import message.RpcResponseMessage;
import server.service.HelloService;
import server.service.ServicesFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Slf4j
@ChannelHandler.Sharable
public class RpcRequestMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcRequestMessage rpcRequestMessage){
        RpcResponseMessage responseMessage = new RpcResponseMessage();
        responseMessage.setMessageType(rpcRequestMessage.getMessageType());
        responseMessage.setSequenceId(rpcRequestMessage.getSequenceId());
        try {
            HelloService helloService = (HelloService) ServicesFactory.getService(Class.forName(rpcRequestMessage.getInterfaceName()));
            Method method = helloService.getClass().getMethod(rpcRequestMessage.getMethodName(), rpcRequestMessage.getParameterTypes());
            Object invoke = method.invoke(helloService, rpcRequestMessage.getParameterValue());
            System.out.println(invoke);
            responseMessage.setReturnValue(invoke);
        } catch (Exception e) {
            responseMessage.setExceptionValue(new Exception("远程调用出错" + e.getCause().getMessage()));
            e.printStackTrace();
        }
        channelHandlerContext.writeAndFlush(responseMessage);
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        RpcRequestMessage rpcRequestMessage = new RpcRequestMessage(
                1,
                "server.service.HelloService",
                "sayHello",
                String.class,
                new Class[]{String.class},
                new Object[]{"张三"}
        );
        HelloService helloService = (HelloService) ServicesFactory.getService(Class.forName(rpcRequestMessage.getInterfaceName()));
        Method method = helloService.getClass().getMethod(rpcRequestMessage.getMethodName(), rpcRequestMessage.getParameterTypes());
        Object invoke = method.invoke(helloService, rpcRequestMessage.getParameterValue());
        System.out.println(invoke);
    }
}
